package test_pkg

import (
	"bytes"
	"fmt"
)

//切片 是对数组一个连续片段的 引用  可以用 make 创建  不需要使用额外的内存并且比使用数组更有效率
// 申明切片 var identifier []type 不用指定长度 初始化之前 默认wei nil 长度为 0
//var slice1 []type = arr1[:]  等价于 slice1 = &arr1  表明 slice1 就等于完整的 arr1 数组

/*
new 和 make 的区别
new(T) 为新的类型 T 分配内存， 返返回一个指向类型为 T，值为 0 的地址的指针，它适用于值类型如: 数组和结构体
make(T) 返回一个类型为 T 的初始值  只适用于 3 种内建的引用类型：切片、map 和 channel
*/

// 将切片传递给函数
func sum(a []int) {
	s := 0
	for i := 0; i < len(a); i++ {
		s += a[i]
	}
	fmt.Println(s)
	// return s
}

func Test_slice() {
	//make([]type, len, cap)  len 长度 cap 容量
	// var s = make([]int, 2, 4) //创建长度为 2 容量为 4 的切片
	var s1 = make([]byte, 5) //长度 = 容量 = 2
	fmt.Printf("%v\n", len(s1))
	fmt.Printf("%v\n", cap(s1))

	s1 = []byte{1, 2}

	//切片传递给函数
	s3 := []byte{3, 4, 5}

	sm := Append(s1, s3)
	fmt.Printf("%v\n", sm)

	//返回前 2 个
	str := "hello go!"
	len := len(str)
	fmt.Printf("len(str): %v\n", len)
	var buffer bytes.Buffer
	buffer.WriteString(str)
	fmt.Printf("buffer.Bytes()[:len-1]: %s\n", buffer.Bytes()[:len-1])
	bPrefix, bSuffix := buffer.Bytes()[:3], buffer.Bytes()[3:]
	fmt.Printf("bPrefix=%s bSuffix=%s\n", string(bPrefix), string(bSuffix))

}

// 自定义切片扩容函数
func Append(slice, data []byte) []byte {
	slen := len(slice)
	dlen := len(data)
	scap := cap(slice)
	nlen := slen + dlen

	nslice := slice
	if nlen > scap {
		nslice = make([]byte, nlen)
		for i, v := range slice {
			nslice[i] = v
		}
	}

	for i, v := range data {
		fmt.Printf("%v\n", i)
		nslice[i+slen] = v
	}

	return nslice

}

// 切片的复制和追加
func Test2() {
	sl_from := []int{1, 2, 3}
	sl_to := make([]int, 5)

	n := copy(sl_to, sl_from)
	fmt.Println(sl_from)
	sl_to[4] = 5
	fmt.Println(sl_to)
	fmt.Printf("Copied %d elements\n", n) // n == 3

	sl3 := []int{1, 2, 3}
	sl3 = append(sl3, 4, 5, 6)
	fmt.Println(sl3)
}
